package com.shop.shoporder.common;

import com.shop.shoporder.entity.order.OrderExport;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


public class ExcelUtil {
    private final static String xls = "xls";
    private final static String xlsx = "xlsx";
    /**
     * 导出Excel
     * @param sheetName sheet名称
     * @param title 标题
     * @param values 内容
     * @param wb HSSFWorkbook对象
     * @return
     */
    public static HSSFWorkbook getHSSFWorkbook(String sheetName, String []title, String [][]values, HSSFWorkbook wb, List<String> listSup, List<OrderExport> orderExports){
        DateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
            DateFormat formatN = new SimpleDateFormat("MM-dd");
        String DataN = formatN.format(new Date());
        String busidstr = format2.format(new Date());

        if(wb == null){
            wb = new HSSFWorkbook();
        }
        for (String strSheetName:listSup) {
            HSSFSheet sheet = wb.createSheet(strSheetName);

//        HSSFCellStyle lo_Style = wb.createCellStyle();
//        lo_Style.setDataFormat(HSSFDataFormat.getBuiltinFormat("@"));
            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
            HSSFRow row = sheet.createRow(0);
            // 第四步，创建单元格，并设置值表头 设置表头居中
            HSSFCellStyle style = wb.createCellStyle();
            style.setDataFormat(HSSFDataFormat.getBuiltinFormat("@"));
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
            style.setAlignment(HSSFCellStyle.BIG_SPOTS);
            //new
            // style .setFillForegroundColor((short) 12);// 设置背景色
            //style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            // 左右上下边框样式
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            // 左右上下边框颜色(深蓝色)
            style.setLeftBorderColor(HSSFColor.BLACK.index);
            style.setRightBorderColor(HSSFColor.BLACK.index);
            style.setTopBorderColor(HSSFColor.BLACK.index);
            style.setBottomBorderColor(HSSFColor.BLACK.index);
            // 背景
            style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);// 设置了背景色才有效果
            style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
            // 单元格字体
            HSSFFont font = wb.createFont();
            font.setFontName("微软雅黑");
            font.setFontHeightInPoints((short) 14);//设置字体大小
//        font.setBoldweight((short) 250);
            style.setFont(font);
            sheet.setColumnWidth(0, 4000);
            sheet.setColumnWidth(1, 6000);
            sheet.setColumnWidth(2, 4000);
            sheet.setColumnWidth(3, 6000);
            sheet.setColumnWidth(4, 15000);
            sheet.setColumnWidth(5, 6000);
            sheet.setColumnWidth(6, 2000);
            sheet.setColumnWidth(7, 8000);
//第一个参数代表列id(从0开始),第2个参数代表宽度值  参考 ："2012-08-10"的宽度为2500
            // 六、设置自动换行:
            //style.setWrapText(true);//设置自动换行
            // 七、合并单元格:
            //Region region1 = new Region(0, (short) 0, 0, (short) 6);//参数1：行号 参数2：起始列号 参数3：行号 参数4：终止列号

            //声明列对象
            HSSFCell cell = null;
            //创建标题
            for(int i=0;i<title.length;i++){
                cell = row.createCell(i);
                cell.setCellValue(title[i]);
                cell.setCellStyle(style);
            }
            //创建内容
//        HSSFCellStyle style1 = wb.createCellStyle();
//        style1.setDataFormat(HSSFDataFormat.getBuiltinFormat("@"));
//       CellStyle style2=wb.createCellStyle();
//       style2.setDataFormat(HSSFDataFormat.getBuiltinFormat("@"));

            List<OrderExport> list=orderExports.stream().filter(c ->c.getSupplier().equals(strSheetName)).collect(Collectors.toList());
            if(list!=null&&list.size()>0){
                String [][] content=new String[list.size()][];
                if(list.size()<=0){
                    content=new String[1][];
                    content[0] = new String[title.length];
                    content[0][0] = "空空如也!";content[0][1] = "空空如也!";content[0][2] = "空空如也!";content[0][3] = "空空如也!";
                    content[0][4] = "空空如也!";content[0][5] = "空空如也!";content[0][6] = "空空如也!";
                }
                for (int i = 0; i < list.size(); i++){
                    OrderExport orderExport=list.get(i);
                    content[i] = new String[title.length];
                    content[i][0] = busidstr+"-"+(i+1);//业务单号
                    content[i][1] = orderExport.getLogName();
                    content[i][2] = orderExport.getPhone();
                    content[i][3] = orderExport.getAddressAll();
                    content[i][4] = orderExport.getGuigeName();
                    content[i][5] = "";
                    content[i][6] = orderExport.getSupplier();
                    content[i][7] =orderExport.getOrderNo();
                }
                for(int i=0;i<content.length;i++){
                    row = sheet.createRow(i + 1);
                    for(int j=0;j<content[i].length;j++){
                        //将内容按顺序赋给对应的列对象
                        row.createCell(j).setCellValue(content[i][j]);
                    }
                }
            }
            //old
//                for(int i=0;i<values.length;i++){
//                    row = sheet.createRow(i + 1);
//                    //row.setRowStyle(style2);
//                    for(int j=0;j<values[i].length;j++){
//                        //将内容按顺序赋给对应的列对象
//                        row.createCell(j).setCellValue(values[i][j]);
//                    }
//                }
            //old
        }
        return wb;
    }

    public static List<File> getHSSFWorkbookZip(String sheetName, String []title, String [][]values, HSSFWorkbook wb1, List<String> listSup, List<OrderExport> orderExports){
        DateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
        String busidstr = format2.format(new Date());

        List<File> listUrl=new ArrayList<>();
        for (String strSheetName:listSup) {

            HSSFWorkbook wb=new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet(strSheetName);

//        HSSFCellStyle lo_Style = wb.createCellStyle();
//        lo_Style.setDataFormat(HSSFDataFormat.getBuiltinFormat("@"));
            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
            HSSFRow row = sheet.createRow(0);
            // 第四步，创建单元格，并设置值表头 设置表头居中
            HSSFCellStyle style = wb.createCellStyle();
            style.setDataFormat(HSSFDataFormat.getBuiltinFormat("@"));
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
            style.setAlignment(HSSFCellStyle.BIG_SPOTS);
            //new
            // style .setFillForegroundColor((short) 12);// 设置背景色
            //style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            // 左右上下边框样式
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            // 左右上下边框颜色(深蓝色)
            style.setLeftBorderColor(HSSFColor.BLACK.index);
            style.setRightBorderColor(HSSFColor.BLACK.index);
            style.setTopBorderColor(HSSFColor.BLACK.index);
            style.setBottomBorderColor(HSSFColor.BLACK.index);
            // 背景
            style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);// 设置了背景色才有效果
            style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
            // 单元格字体
            HSSFFont font = wb.createFont();
            font.setFontName("微软雅黑");
            font.setFontHeightInPoints((short) 14);//设置字体大小
//        font.setBoldweight((short) 250);
            style.setFont(font);
            sheet.setColumnWidth(0, 4000);
            sheet.setColumnWidth(1, 6000);
            sheet.setColumnWidth(2, 4000);
            sheet.setColumnWidth(3, 6000);
            sheet.setColumnWidth(4, 15000);
            sheet.setColumnWidth(5, 6000);
            sheet.setColumnWidth(6, 2000);
            sheet.setColumnWidth(7, 8000);
//第一个参数代表列id(从0开始),第2个参数代表宽度值  参考 ："2012-08-10"的宽度为2500
            // 六、设置自动换行:
            //style.setWrapText(true);//设置自动换行
            // 七、合并单元格:
            //Region region1 = new Region(0, (short) 0, 0, (short) 6);//参数1：行号 参数2：起始列号 参数3：行号 参数4：终止列号

            //声明列对象
            HSSFCell cell = null;
            //创建标题
            for(int i=0;i<title.length;i++){
                cell = row.createCell(i);
                cell.setCellValue(title[i]);
                cell.setCellStyle(style);
            }
            //创建内容
//        HSSFCellStyle style1 = wb.createCellStyle();
//        style1.setDataFormat(HSSFDataFormat.getBuiltinFormat("@"));
//       CellStyle style2=wb.createCellStyle();
//       style2.setDataFormat(HSSFDataFormat.getBuiltinFormat("@"));

            String finalStrSheetName = strSheetName;
//            System.out.println("finalStrSheetName:"+finalStrSheetName);
//            for (OrderExport orderExport: orderExports) {
//                System.out.println("orderExport:"+orderExport.getSupplier());
//            }
            List<OrderExport> list=orderExports.stream().filter(c ->c.getSupplier().equals(finalStrSheetName)).collect(Collectors.toList());
            //System.out.println("finalStrSheetName:"+finalStrSheetName+" size:"+list.size());
            if(list!=null&&list.size()>0){
                String [][] content=new String[list.size()][];
                if(list.size()<=0){
                    content=new String[1][];
                    content[0] = new String[title.length];
                    content[0][0] = "空空如也!";content[0][1] = "空空如也!";content[0][2] = "空空如也!";content[0][3] = "空空如也!";
                    content[0][4] = "空空如也!";content[0][5] = "空空如也!";content[0][6] = "空空如也!";
                }
                for (int i = 0; i < list.size(); i++){
                    OrderExport orderExport=list.get(i);
                    content[i] = new String[title.length];
                    content[i][0] = busidstr+"-"+(i+1);//业务单号
                    content[i][1] = orderExport.getOrderNo();
                    content[i][2] = orderExport.getLogName();
                    content[i][3] = orderExport.getPhone();
                    content[i][4] = orderExport.getAddressAll();
                    content[i][5] = orderExport.getGuigeName();
                    content[i][6] = "";
                    content[i][7] = orderExport.getSupplier();
                }
                for(int i=0;i<content.length;i++){
                    row = sheet.createRow(i + 1);
                    for(int j=0;j<content[i].length;j++){
                        //将内容按顺序赋给对应的列对象
                        row.createCell(j).setCellValue(content[i][j]);
                    }
                }
            }
            //old
//                for(int i=0;i<values.length;i++){
//                    row = sheet.createRow(i + 1);
//                    //row.setRowStyle(style2);
//                    for(int j=0;j<values[i].length;j++){
//                        //将内容按顺序赋给对应的列对象
//                        row.createCell(j).setCellValue(values[i][j]);
//                    }
//                }
            //old
            //保存excel
            int rowCount=sheet.getLastRowNum();
//            System.out.println("rowCount:"+rowCount);
//            System.out.println("strSheetName:"+strSheetName);
            if(rowCount>0){
                try {
                    String path="/usr/local/mall_uploads/logistics";
                    File uploadPath=new File(path);
                    if(!uploadPath.exists()){
                        uploadPath.mkdirs();
                    }
                    strSheetName=strSheetName+System.currentTimeMillis()+".xls";
                    FileOutputStream fileOut = new FileOutputStream(uploadPath+"/"+strSheetName);
                    String url="/logistics/"+strSheetName;

                    //封装路径
                    File filex = new File(ResourceUtils.getURL("/usr/local/mall_uploads/").getPath());
                    String aFilePath=filex+url;
                    File xf=new File(aFilePath);
                    //String aFileName = xf.getName();
                    listUrl.add(xf);
                    //封装路径

                    wb.write(fileOut);
                    fileOut.close();
                }
                catch (Exception e){
                    e.printStackTrace();
                }
            }
        }

        return listUrl;
    }


    /**
     * 读入excel文件，解析后返回
     * @param file
     * @throws IOException
     */
    public static List<String[]> readExcel(MultipartFile file) throws Exception {
        //检查文件
        checkFile(file);
        //获得Workbook工作薄对象
        Workbook workbook = getWorkBook(file);
        //创建返回对象，把每行中的值作为一个数组，所有行作为一个集合返回
        List<String[]> list = new ArrayList<String[]>();
        if(workbook != null){
//            for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){
            //只循环第一个工作表
            for(int sheetNum = 0;sheetNum < 1;sheetNum++){
                //获得当前sheet工作表
                Sheet sheet = workbook.getSheetAt(sheetNum);
                if(sheet == null){
                    continue;
                }
                //获得当前sheet的开始行
                int firstRowNum  = sheet.getFirstRowNum();
                //获得当前sheet的结束行
                int lastRowNum = sheet.getLastRowNum();

// 循环除了第一行的所有行
//                for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){

                //循环所有
                for(int rowNum = firstRowNum;rowNum <= lastRowNum;rowNum++){

                    //获得当前行
                    Row row = sheet.getRow(rowNum);
                    if(row == null ||row.getPhysicalNumberOfCells()==0){
                        continue;
                    }
                    //获得当前行的开始列
                    int firstCellNum = row.getFirstCellNum();
                    //获得当前行的列数
                    int lastCellNum = row.getPhysicalNumberOfCells();
                    String[] cells = new String[row.getPhysicalNumberOfCells()];
                    //循环当前行
                    for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){
                        Cell cell = row.getCell(cellNum);
                        cells[cellNum] = getCellValue(cell);
                    }
                    list.add(cells);
                }
            }
            workbook.close();
        }
        return list;
    }
    public static void checkFile(MultipartFile file) throws IOException{
        //判断文件是否存在
        if(null == file){

            throw new FileNotFoundException("文件不存在！");
        }
        //获得文件名
        String fileName = file.getOriginalFilename();
        //判断文件是否是excel文件
        if(!fileName.endsWith(xls) && !fileName.endsWith(xlsx)){

            throw new IOException(fileName + "不是excel文件");
        }
    }
    public static Workbook getWorkBook(MultipartFile file) {
        //获得文件名
        String fileName = file.getOriginalFilename();
        //创建Workbook工作薄对象，表示整个excel
        Workbook workbook = null;
        try {
            //获取excel文件的io流
            InputStream is = file.getInputStream();
            //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
            if(fileName.endsWith(xls)){
                //2003
                workbook = new HSSFWorkbook(is);
            }else if(fileName.endsWith(xlsx)){
                //2007
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {

        }
        return workbook;
    }
    public static String getCellValue(Cell cell){
        String cellValue = "";
        if(cell == null){
            return cellValue;
        }
        //把数字当成String来读，避免出现1读成1.0的情况
        if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
            cell.setCellType(Cell.CELL_TYPE_STRING);
        }
        //判断数据的类型
        switch (cell.getCellType()){
            case Cell.CELL_TYPE_NUMERIC: //数字
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            case Cell.CELL_TYPE_STRING: //字符串
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case Cell.CELL_TYPE_BOOLEAN: //Boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA: //公式
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case Cell.CELL_TYPE_BLANK: //空值
                cellValue = "";
                break;
            case Cell.CELL_TYPE_ERROR: //故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }



    // 存在的问题
    /*
     * 其实有时候我们希望得到的数据就是excel中的数据，可是最后发现结果不理想
     * 如果你的excel中的数据是数字，你会发现Java中对应的变成了科学计数法。
     * 所以在获取值的时候就要做一些特殊处理来保证得到自己想要的结果
     * 网上的做法是对于数值型的数据格式化，获取自己想要的结果。
     * 下面提供另外一种方法，在此之前，我们先看一下poi中对于toString()方法:
     *
     * 该方法是poi的方法，从源码中我们可以发现，该处理流程是：
     * 1.获取单元格的类型
     * 2.根据类型格式化数据并输出。这样就产生了很多不是我们想要的
     * 故对这个方法做一个改造。
     */
    /*public String toString(){
        switch(getCellType()){
            case CELL_TYPE_BLANK:
                return "";
            case CELL_TYPE_BOOLEAN:
                return getBooleanCellValue() ? "TRUE" : "FALSE";
            case CELL_TYPE_ERROR:
                return ErrorEval.getText(getErrorCellValue());
            case CELL_TYPE_FORMULA:
                return getCellFormula();
            case CELL_TYPE_NUMERIC:
                if(DateUtil.isCellDateFormatted(this)){
                    DateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy")
                    return sdf.format(getDateCellValue());
                }
                return getNumericCellValue() + "";
            case CELL_TYPE_STRING:
                return getRichStringCellValue().toString();
            default :
                return "Unknown Cell Type:" + getCellType();
        }
    }*/

    /**
     * 改造poi默认的toString（）方法如下
     * @Title: getStringVal
     * @Description: 1.对于不熟悉的类型，或者为空则返回""控制串
     *               2.如果是数字，则修改单元格类型为String，然后返回String，这样就保证数字不被格式化了
     * @param @param cell
     * @param @return    设定文件
     * @return String    返回类型
     * @throws
     */
    public static String getStringVal(HSSFCell cell) {
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_BOOLEAN:
                return cell.getBooleanCellValue() ? "TRUE" : "FALSE";
            case Cell.CELL_TYPE_FORMULA:
                return cell.getCellFormula();
            case Cell.CELL_TYPE_NUMERIC:
                cell.setCellType(Cell.CELL_TYPE_STRING);
                return cell.getStringCellValue();
            case Cell.CELL_TYPE_STRING:
                return cell.getStringCellValue();
            default:
                return "";
        }
    }

}
